デプロイ前のコンプライアンスチェック!CloudFormation Guardを試してみた
CloudFormation テンプレート(以下、CFn テンプレート)が、ポリシーガイドラインに準拠しているか確認できるコマンドラインツールとして、CloudFormation Guard(以下、CFn Guard)が公開されました。
CFn Guard は、2020 年 10 月 1 日から一般提供されています。
これまで、Security Hub のセキュリティ標準や Config 適合パックを用いて、AWS 環境がコンプライアンスに準拠しているか調べられます。
CFn Guard では、CFn テンプレートが定義したルールを満たしているかをチェックでき、デプロイする前にコンプライアンスに準拠しているかチェックできます。
デプロイ前に CFn Guard でチェックすることによって、より安全なデプロイを実現できます。
やってみた
実際に使いながら何をできるか確認していきます。まずは GitHub の手順に従って、ローカルで CFn Guard を試します。
0. インストール
Mac で実行する場合は、Homebrew からインストールできます。
brew install cloudformation-guard
他の OS 実行環境でのインストール方法については、こちらを参照ください。
1. ローカルで実行
以下のような EBS ボリュームを作成する CFn テンプレートを作成します。
AWSTemplateFormatVersion: "2010-09-09"
Description: EBS Volume Stack
Resources:
NewVolume:
Type: AWS::EC2::Volume
Properties:
Size: 500
Encrypted: false
AvailabilityZone: !Select
- 0
- Fn::GetAZs: !Ref AWS::Region
NewVolume2:
Type: AWS::EC2::Volume
Properties:
Size: 50
Encrypted: false
AvailabilityZone: !Select
- 0
- Fn::GetAZs: !Ref AWS::Region
続いて、以下のルールセットのファイルを作成します。
let encryption_flag = true
AWS::EC2::Volume Encrypted == %encryption_flag
AWS::EC2::Volume Size <= 100
1 行目は let 変数名 = 値
のフォーマッットで変数を定義しています。
3,4 行目では リソースタイプ プロパティ 演算子 値
のフォーマットで CloudFormation リソースタイプのプロパティに期待する値を指定しています。これが CFn Guard における基本的なルールの書き方になります。
ルールの書き方の詳細につきましては、こちらを参照ください。
見てのとおりではありますが、ここでは
- EBS ボリュームで暗号化がされていること
- ボリュームサイズが 100GB 以下であること
を定義しています。
テンプレートとルールができたので、cfn-guard check
コマンドでチェックしています。
$ cfn-guard check --template ebs.yml --rule_set ebs_volume_template.ruleset
[NewVolume2]failed because[Encrypted]is[false]and the permitted value is[true]
[NewVolume]failed because[Encrypted]is[false]and the permitted value is[true]
[NewVolume]failed because[Size]is[500]and the permitted value is[<= 100]
Number of failures: 3
NewVolume と NewVolume2 は暗号化してなかっため、エラーとなってます。
また、NewVolume はボリュームサイズが 100GB を超えているため、エラーとなっています。
では、エラーとなった箇所を以下の通り修正します。
AWSTemplateFormatVersion: "2010-09-09"
Description: EBS Volume Stack
Resources:
NewVolume:
Type: AWS::EC2::Volume
Properties:
Size: 50
Encrypted: true
AvailabilityZone: !Select
- 0
- Fn::GetAZs: !Ref AWS::Region
NewVolume2:
Type: AWS::EC2::Volume
Properties:
Size: 50
Encrypted: true
AvailabilityZone: !Select
- 0
- Fn::GetAZs: !Ref AWS::Region
cfn-guard check
コマンドを再度実行します。
$ cfn-guard check --template ebs.yml --rule_set ebs_volume_template.ruleset
エラーなく、CFn Guard が完了しました!
ルールセットは、サンプルでいくつか用意されておりますので、お試しで使っていただければと思います。
2. 自動ルールの生成
CFn Guard では、cfn-guard rulegen
コマンドを使うことにより、既存の CFn テンプレートからルールを自動生成できます。
$ cfn-guard rulegen ebs.yml
AWS::EC2::Volume AvailabilityZone ==[0,{"Fn::GetAZs":"AWS::Region"}]
AWS::EC2::Volume Encrypted == true
AWS::EC2::Volume Size == 50
ルールが生成されましたら、必要に応じでルールの追加や削除をして、チェックで使用するルールができあがります。
さいごに
デプロイ前にコンプライアンスチェックできる CloudFormation Guard を試してみました。
組織に合わせたルールを一度定義しデプロイフローに組み込むことで、より安全なデプロイが可能になります。今回はローカルで試しましたが、実運用を想定して CI/CD パイプラインに組み込む構成も試したいです。
CloudForamtion を使っている環境で、ぜひ使いたいツールだと思います。
プロダクト環境で使うには、rule-set の運用をどうするか、ルールセットを無視したい場合どうすといいのかは検討必要そうです。内部統制と開発者の職務分離するためにも、コードと rule-set を管理するリポジトリは分けて権限を絞ると良さそうな気はしてます。統制側で例外ルールを管理できると良さそうですがが、どうするといいのか私にはいいアイデアが思いつきませんでした。(そもそも例外となるルールはあってはいけないと考えるべきかもしれませんが)案ある方いましたらコメントいただけますと幸いです。